package com.ruoyi.common.utils.security;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.jwt.Claims;
import cn.hutool.jwt.JWT;

import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.project.erp.member.domain.ErpMember;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * JwtToken生成的工具类
 * Created by macro on 2018/4/26.
 */
@Component
public class JwtTokenUtilHutool {
    private static final Logger LOGGER = LoggerFactory.getLogger(JwtTokenUtilHutool.class);
    private static final String CLAIM_KEY_USERNAME = "sub";
    private static final String CLAIM_KEY_CREATED = "created";
    @Value("${jwt.secret}")
    private String secret;
    @Value("${jwt.expiration}")
    private Integer expiration;


    private final String MEMBER_ID = "memberId";
    private final String EXPIRATION = "exp";
    private final Integer NORMAL_STATUS = 1;
//    private  final String MEMBER_PASSWORD = "memberPassword";


    /**
     * 根据用户信息生成token
     */
    public String generateToken(ErpMember erpMember) {
        String token = JWT.create()
                .setPayload(MEMBER_ID, erpMember.getMemberId())
                .setPayload(EXPIRATION, generateExpirationDate())
//                .setExpiresAt(generateExpirationDate())
//                .setPayload(EXPIRATION, generateExpirationDate())
//                .setPayload(MEMBER_PASSWORD, member.get())
                .setKey(secret.getBytes(StandardCharsets.UTF_8))
                .sign();
        return token;
    }


//    /**
//     * 从token中获取登录用户名
//     */
//    public String getUserNameFromToken(String token) {
//        String username;
//        try {
//            Claims claims = getClaimsFromToken(token);
//            username =  claims.getSubject();
//        } catch (Exception e) {
//            username = null;
//        }
//        return username;
//    }

//    /**
//     * 验证token是否还有效
//     *
//     * @param token       客户端传入的token
//     * @param member 从数据库中查询出来的用户信息
//     */
//    public boolean validateToken(String token, Member member) {
//        String username = getUserNameFromToken(token);
//        return username.equals(member.getMemberId()) && !isTokenExpired(token);
//    }


    /**
     * 验证token是否还有效
     *
     * @param token  客户端传入的token
     * @param erpMember 从数据库中查询出来的用户信息
     */
    public boolean validateToken(String token, ErpMember erpMember) {
        String memberId = String.valueOf(getInfoFromToken(token, MEMBER_ID));
        //检查用户状态是否激活。
        if(!NORMAL_STATUS.equals(erpMember.getMemberStatus())){
            return false ;
        }

        //对比用户编码是否一致
        boolean equals = memberId.equals(String.valueOf(erpMember.getMemberId()));
//        return equals && !isTokenExpired(token);
        return equals ;
//        return memberId.equals(member.getMemberId());
    }


    /**
     * 判断token是否已经失效
     */
    public boolean isTokenExpired(String token) {
        String expiredDateString = (String) getInfoFromToken(token, EXPIRATION);

        Date expiredDate = DateUtil.parse(expiredDateString);
//        Date  expiredDate = new Date( Integer.valueOf(String.valueOf(expiredDateObject)));
        return expiredDate.before(new Date());
    }


//
//    /**
//     * 从token中获取过期时间
//     */
//    private Date getExpiredDateFromToken(String token) {
//        Claims claims = getClaimsFromToken(token);
//        return claims.getExpiration();
//    }
//


    /**
     * 验证token是否还有效
     *
     * @param token    客户端传入的token
     * @param memberId
     */
    public boolean validateTokenByMemberId(String token, String memberId) {
        Object memberIdFromToken = getInfoFromToken(token, MEMBER_ID);
        return memberIdFromToken.equals(memberId);
    }


    /**
     * 判断token是否可以被刷新
     */
    public boolean canRefresh(String token) {
        return !isTokenExpired(token);
    }


    /**
     * 验证token是否还有效
     *
     * @param token 客户端传入的token
     * @param key
     */
    public Object getInfoFromToken(String token, String key) {

        JWT jwt = JWT.of(token);
        return jwt.getPayload(key);
    }


//    /**
//     * 根据负责生成JWT的token
//     */
//    private String generateToken(Map<String, Object> claims) {
//        return Jwts.builder()
//                .setClaims(claims)
//                .setExpiration(generateExpirationDate())
//                .signWith(SignatureAlgorithm.HS512, secret)
//                .compact();
//    }

//    /**
//     * 从token中获取JWT中的负载
//     */
//    private cn.hutool.jwt.Claims getClaimsFromToken(String token) {
//        cn.hutool.jwt.Claims claims = null;
//        try {
//            claims = Jwts.parser()
//                    .setSigningKey(secret)
//                    .parseClaimsJws(token)
//                    .getBody();
//        } catch (Exception e) {
//            LOGGER.info("JWT格式验证失败:{}",token);
//        }
//        return claims;
//    }

    /**
     * 生成token的过期时间
     */
    private String generateExpirationDate() {
//当前时间字符串，格式：yyyy-MM-dd HH:mm:ss
        String now = DateUtil.now();
        Date date = DateUtil.parse(now);
        Date expirationDate = DateUtil.offset(date, DateField.MINUTE, expiration);

//        Date date = new Date(System.currentTimeMillis() + expiration * 1000);
        String format = DateUtil.format(expirationDate, DateUtils.YYYY_MM_DD_HH_MM_SS);

        return format;
    }

//    /**
//     * 从token中获取登录用户名
//     */
//    public String getUserNameFromToken(String token) {
//        String username;
//        try {
//            Claims claims = getClaimsFromToken(token);
//            username =  claims.getSubject();
//        } catch (Exception e) {
//            username = null;
//        }
//        return username;
//    }
//


//    /**
//     * 从token中获取过期时间
//     */
//    private Date getExpiredDateFromToken(String token) {
//        Claims claims = getClaimsFromToken(token);
//        return claims.getExpiration();
//    }


}